#include "ftr.h"
#include "rectype.h"
#include "util.h"
#include "nmfield.h"
#include "cnfield.h"

#include "nmarrfield.h"
#include "nmarrfield.cpp"

#include "stdffield.h"
#include "stdffield.cpp"

using namespace std;
using namespace opsrc::stdf;

Ftr::Ftr()
{}


Ftr::Ftr(stdf_rec _stdfrec, int _reclen, std::ios::pos_type _fileRecFirstBytePosition, int _orderindex,  endian e, char* buf)
:RecBase(_stdfrec, _reclen, _fileRecFirstBytePosition, _orderindex),en(e){
    if (buf!= 0)
        readFields(buf);
}

Ftr::~Ftr() {
}

const StdfField<long> Ftr::getTestNumber() const {
    return test_num;
}

void Ftr::setTestNumber(StdfField<long> testnum) {
    test_num = testnum;
}

const StdfField<int> Ftr::getHeadNumber() const {
    return head_num;
}

void Ftr::setHeadNumber(StdfField<int> headnum) {
    head_num = headnum;
}

const StdfField<int> Ftr::getSiteNumber() const {
    return site_num;
}

void Ftr::setSiteNumber(StdfField<int> sitenum) {
    site_num = sitenum;
}

const StdfField< vector<bool> > Ftr::getTestFlag() const {
    return test_flag;
}

void Ftr::setTestFlag(StdfField<vector<bool> > testflag) {
    test_flag = testflag;
}

const StdfField<vector<bool> > Ftr::getOptionFlag() const {
    return opt_flag;
}

void Ftr::setOptionFlag(StdfField<vector<bool> > optflag) {
    opt_flag = optflag;
}

const StdfField<int> Ftr::getCycleCount() const {
    return cycl_cnt;
}

void Ftr::setCycleCount(StdfField<int> cyclcnt){
    cycl_cnt = cyclcnt;
}

const StdfField<long> Ftr::getRelativeVectorAddress() const {
    return rel_vadr;
}

void Ftr::setRelativeVectorAddress(StdfField<long> relvadr) {
    rel_vadr = relvadr;
}

const StdfField<long> Ftr::getRepeatedVectorCount() const {
    return rept_cnt;
}

void Ftr::setRepeatedVectorCount(StdfField<long> reptcnt)  {
    rept_cnt = reptcnt;
}

const StdfField<long> Ftr::getPinFailureCount() const {
    return num_fail;
}

void Ftr::setPinFailureCount(StdfField<long> numfail) {
    num_fail = numfail;
}

const StdfField<unsigned long> Ftr::getXlogicalDeviceAddressFailure() const {
    return xfail_ad;
}

void Ftr::setXlogicalDeviceAddressFailure(StdfField<unsigned long> xfailad) {
    xfail_ad = xfailad;
}

const StdfField<unsigned long> Ftr::getYlogicalDeviceAddressFailure() const {
    return yfail_ad;
}

void Ftr::setYlogicalDeviceAddressFailure(StdfField<unsigned long> yfailad) {
    yfail_ad = yfailad;
}

const StdfField<int> Ftr::getVectorOffset() const {
    return vect_off;
}

void Ftr::setVectorOffset(StdfField<int> vectoff) {
    vect_off = vectoff;
}

const StdfField<int> Ftr::getPmrCountIndexes() const {
    return rtn_icnt;
}

void Ftr::setPmrCountIndexes(StdfField<int> rtnicnt) {
    rtn_icnt = rtnicnt;
}

const StdfField<int> Ftr::getProgramStateIndexes() const {
    return pgm_icnt;
}

void Ftr::setProgramStateIndexes(StdfField<int> pgmicnt) {
    pgm_icnt = pgmicnt;
}

const StdfField<vector<int> > Ftr::getPmrArrayData() const {
    return rtn_indx;
}

void Ftr::setPmrArrayData(StdfField<vector<int> > rtnindx) {
    rtn_indx = rtnindx;
}

const StdfField<vector<int> > Ftr::getPmrArrayState() const {
    return rtn_stat;
}

void Ftr::setPmrArrayState(StdfField<vector<int> > rtnstat) {
    rtn_stat = rtnstat;
}

const StdfField<vector<int> > Ftr::getProgramsStateIndexArray() const {
    return pgm_indx;
}

void Ftr::setProgramStateArray(StdfField<vector<int> > pgmindx) {
    pgm_indx = pgmindx;
}

const StdfField<vector<int> > Ftr::getProgramStateDataArray() const {
    return pgm_stat;
}

void Ftr::setProgramStateDataArray(StdfField<vector<int> > pgmstat) {
    pgm_stat = pgmstat;
}

const StdfField<int> Ftr::getFailPinBitMapLength() const {
    return fail_pin;
}

void Ftr::setFailPinBitMapLength(StdfField<int> failpin) {
    fail_pin = failpin;
}

const StdfField<string> Ftr::getVectorModulePatternName() const {
    return vect_nam;
}

void Ftr::setVectorModulePatternName(StdfField<string> vectnam) {
    vect_nam = vectnam;
}


const StdfField<string> Ftr::getTimeSetName() const {
    return time_set;
}

void Ftr::setTimeSetName(StdfField<string> timeset) {
    time_set = timeset;
}


const StdfField<string> Ftr::getVectorOpCode() const {
    return op_code;
}

void Ftr::setVectorOpCode(StdfField<string> opcode) {
    op_code = opcode;
}



const StdfField<string> Ftr::getDescriptiveText() const {
    return test_txt;
}

void Ftr::setDescriptiveText(StdfField<string> testtxt) {
    test_txt = testtxt;
}

const StdfField<string> Ftr::getAlarmId() const {
    return alrm_id;
}

void Ftr::setAlarmId(StdfField<string> alrmid) {
    alrm_id = alrmid;
}

const StdfField<string> Ftr::getAdditonalProgramInfo() const {
    return prog_txt;
}

void Ftr::setAdditionalProgramInfo(StdfField<string> progtxt) {
    prog_txt = progtxt;
}

const StdfField<string> Ftr::getAdditionalResultInfo() const {
    return rslt_txt;
}

void Ftr::setAdditionalResultInfo(StdfField<string> rslttxt) {
    rslt_txt = rslttxt;
}

const StdfField<int> Ftr::getPatternGenertorNumber() const {
    return patg_num;
}

void Ftr::setPatternGeneratorNumber(StdfField<int> patgnum) {
    patg_num = patgnum;
}

const StdfField<int> Ftr::getEnabledComparatorBitMap() const {
    return spin_map;
}

void Ftr::setEnabledComparatorBitMap(StdfField<int> spinmap) {
    spin_map = spinmap;
}


void Ftr::readFields(char *buf) {

#if _DEBUG
    cout << "stdfrec= FTR , filebytestartposition= " <<   getFileRecByteStartPosition() << ", recbytecount= " << reclen <<endl;
#endif

    int curpos = 0;
    // Read test number , 4 byte
    NmField<long, 4> testnum(buf+curpos, en);
    test_num.set(testnum.getData(), curpos, testnum.getByteCount(), testnum.getTotalByteCount());
    curpos += test_num.getTotalByteCount();

#if _DEBUG
    cout << "after test_num curpos=" <<   curpos   << endl;
#endif

    // Read Head num, 1 byte
    if(curpos < reclen - 1) {
        NmField<unsigned int, 1> headnum(buf+curpos, en);
        head_num.set(headnum.getData(), curpos, headnum.getByteCount(), headnum.getTotalByteCount());
        curpos += head_num.getTotalByteCount();
    }

#if _DEBUG
    cout << "after head_num curpos=" <<   curpos   << endl;
#endif

    // Read Site num, 1 byte
    if (curpos < reclen - 1)  {
        NmField<unsigned int, 1> sitenum(buf+curpos, en);
        site_num.set(sitenum.getData(), curpos, sitenum.getByteCount(), sitenum.getTotalByteCount());
        curpos += site_num.getTotalByteCount();
    }

#if _DEBUG
    cout << "after site_num curpos=" <<   curpos   << endl;
#endif


    // Read test flag
    if (curpos < reclen-1 ) {
        NmArrField<bool,1,vector> testflag(buf+curpos, en,1 );
        test_flag.set(testflag.getData(), curpos, testflag.getByteCount(), testflag.getTotalByteCount());
        curpos += test_flag.getTotalByteCount();
    }

#if _DEBUG
    cout << "after test_flag curpos=" <<   curpos   << endl;
#endif

    // Read opt flag

    if (curpos < reclen-1) {
        NmArrField<bool, 1 > optflag(buf+curpos,en,1);
        opt_flag.set(optflag.getData(), curpos, optflag.getByteCount(), optflag.getTotalByteCount());
        curpos += opt_flag.getTotalByteCount();
    }

#if _DEBUG
    cout << "after opt_flag curpos=" <<   curpos   << endl;
#endif


    // Read cycle count
    if (curpos < reclen-1) {
        if ( getFlagSetting(opt_flag, 0) )  {
            NmField<unsigned int, 4 > cyclcnt(buf+curpos, en);
            cycl_cnt.set(cyclcnt.getData(), curpos, cyclcnt.getByteCount(), cyclcnt.getTotalByteCount());
            curpos += cycl_cnt.getTotalByteCount();
        }
        else {
            curpos += 4;  // Need to advance cur file byte location pointer
        }
     }

#if _DEBUG
    cout << "after cycl_cnt curpos=" <<   curpos   << endl;
#endif

     // Read relative vector address
     if (curpos < reclen-1) {
        if ( getFlagSetting(opt_flag, 1) )  {
            NmField<unsigned int, 4 > relvadr(buf+curpos, en);
            rel_vadr.set(relvadr.getData(), curpos, relvadr.getByteCount(), relvadr.getTotalByteCount());
            curpos += rel_vadr.getTotalByteCount();
        }
        else {
            curpos += 4;  // Need to advance cur file byte location pointer
        }
     }

#if _DEBUG
    cout << "after rel_vadr curpos=" <<   curpos   << endl;
#endif

     // Read repeat count vector
     if (curpos < reclen-1) {
        if (getFlagSetting(opt_flag, 2)) {
            NmField<unsigned int, 4 > reptcnt(buf+curpos, en);
            rept_cnt.set(reptcnt.getData(), curpos, reptcnt.getByteCount(), reptcnt.getTotalByteCount());
            curpos += rept_cnt.getTotalByteCount();
        }
        else {
            curpos += 4;  // Need to advance cur file byte location pointer
        }
     }

#if _DEBUG
    cout << "after rept_cnt curpos=" <<   curpos   << endl;
#endif

    // Read Number of pin failures
    if (curpos < reclen-1) {
        if (getFlagSetting(opt_flag, 3)) {
            NmField<unsigned int, 4 > numfail(buf+curpos, en);
            num_fail.set(numfail.getData(), curpos, numfail.getByteCount(), numfail.getTotalByteCount());
            curpos += num_fail.getTotalByteCount();
        }
        else {
            curpos += 4;  // Need to advance cur file byte location pointer
        }
     }

#if _DEBUG
    cout << "after num_fail curpos=" <<   curpos   << endl;
#endif

    // Read X fail address vector
    if (curpos < reclen-1) {
        if (getFlagSetting(opt_flag, 4)) {
            NmField<long, 4 > xfailad(buf+curpos, en);
            xfail_ad.set(xfailad.getData(), curpos, xfailad.getByteCount(), xfailad.getTotalByteCount());
            curpos += xfail_ad.getTotalByteCount();
        }
        else {
            curpos += 4;  // Need to advance cur file byte location pointer
        }
    }

#if _DEBUG
    cout << "after xfail_ad curpos=" <<   curpos   << endl;
#endif

    // Read Y fail address vector
    if (curpos < reclen-1) {
        if (getFlagSetting(opt_flag, 4)) {
            NmField<long, 4 > yfailad(buf+curpos, en);
            yfail_ad.set(yfailad.getData(), curpos, yfailad.getByteCount(), yfailad.getTotalByteCount());
            curpos += yfail_ad.getTotalByteCount();
        }
        else {
            curpos += 4;  // Need to advance cur file byte location pointer
        }
    }

 #if _DEBUG
    cout << "after yfail_ad curpos=" <<   curpos   << endl;
#endif

    // Read offset for vector of interest
    if (curpos < reclen-1) {
        if (getFlagSetting(opt_flag, 5)) {
         NmField<int, 2 > vectoff(buf+curpos, en);
         vect_off.set(vectoff.getData(), curpos, vectoff.getByteCount(), vectoff.getTotalByteCount());
         curpos += vect_off.getTotalByteCount();
        }
        else {
            curpos += 2;  // Need to advance cur file byte location pointer
        }
    }

#if _DEBUG
    cout << "after vect_off curpos=" <<   curpos   << endl;
#endif

/*
    if( curpos == reclen )
    {

        if( StdfConfig::instance()->printScreen() )
        {
            cout << "FTR:"
                    << test_num.getData() << "|"
                    << head_num.getData() << "|"
                    << site_num.getData() << "|";
            if(testflag.at(7) == "1") cout << "F" << "|";
            else cout << "P" << "|";
            if(testflag.at(3) == "1") cout << "T";
            if(testflag.at(5) == "1") cout << "X";
            cout << "|";
            cout << vect_nam.getData() << "|"
                    << time_set.getData() << "|"
                    << cycl_cnt.getData() << "|"
                    << rel_vadr.getData() << "|"
                    << rept_cnt.getData() << "|"
                    << num_fail.getData() << "|"
                    << xfail_ad.getData() << "|"
                    << yfail_ad.getData() << endl;
        }
        return;
    }
*/



    // Read PMR count of return indexes
    if (curpos < reclen-1) {
        NmField<unsigned int, 2 > rtnicnt(buf+curpos, en);
        rtn_icnt.set(rtnicnt.getData(), curpos, rtnicnt.getByteCount(), rtnicnt.getTotalByteCount());
        curpos += rtn_icnt.getTotalByteCount();
    }
#if _DEBUG
    cout << "after rtn_icnt curpos=" <<   curpos   << endl;
#endif

    // Read programmable count of return indexes
    if (curpos < reclen -1) {
        NmField<unsigned int, 2 > pgmicnt(buf+curpos, en);
        pgm_icnt.set(pgmicnt.getData(), curpos, pgmicnt.getByteCount(), pgmicnt.getTotalByteCount());
        curpos += pgm_icnt.getTotalByteCount();
    }
#if _DEBUG
    cout << "after pgm_icnt curpos=" <<   curpos   << endl;
#endif

    // Read array of returned data PMR indexes
    if (curpos < reclen-1){
        NmArrField<int, 2 > rtnindx(buf+curpos, en, rtn_icnt.getData() );
        rtn_indx.set(rtnindx.getData(), curpos, rtnindx.getByteCount(), rtnindx.getTotalByteCount());
        curpos += rtn_indx.getTotalByteCount();
    }
#if _DEBUG
    cout << "after rtn_indx curpos=" <<   curpos   << endl;
#endif

    // Read array of returned states
    if (curpos < reclen-1) {
        NmArrField<int, 1 > rtnstat(buf+curpos, en,rtn_icnt.getData() );
        rtn_stat.set(rtnstat.getData(), curpos, rtnstat.getByteCount(), rtnstat.getTotalByteCount());
        curpos += rtn_stat.getTotalByteCount();
    }
#if _DEBUG
    cout << "after rtn_stat curpos=" <<   curpos   << endl;
#endif

    // Read array of programmed index
    if ( curpos < reclen-1 ) {
        NmArrField<int, 2 > pgmindx(buf+curpos, en, pgm_icnt.getData() );
        pgm_indx.set(pgmindx.getData(), curpos, pgmindx.getByteCount(), pgmindx.getTotalByteCount());
        curpos += pgm_indx.getTotalByteCount();
    }
#if _DEBUG
    cout << "after pgm_indx curpos=" <<   curpos   << endl;
#endif

    // Read array of programmed states
    if ( curpos < reclen-1 ) {
        NmArrField<int, 1 > pgmstat(buf+curpos, en, pgm_icnt.getData() );
        pgm_stat.set(pgmstat.getData(), curpos, pgmstat.getByteCount(), pgmstat.getTotalByteCount());
        curpos += pgm_stat.getTotalByteCount();
    }
#if _DEBUG
    cout << "after pgm_stat curpos=" <<   curpos   << endl;
#endif

    // Read fail pin
    if (curpos < reclen -1){
        NmField<int, 2 > failpin(buf+curpos, en);
        fail_pin.set(failpin.getData(), curpos, failpin.getByteCount(), failpin.getTotalByteCount());
        curpos += fail_pin.getTotalByteCount();
    }
#if _DEBUG
    cout << "after fail_pin curpos=" <<   curpos   << endl;
#endif

    // Read vector name
    if (curpos < reclen -1){
        CnField<string> vectnam(buf+curpos, en);
        vect_nam.set(vectnam.getData(), curpos, vectnam.getByteCount(), vectnam.getTotalByteCount());
        curpos += vect_nam.getTotalByteCount();
    }
#if _DEBUG
    cout << "after vect_nam curpos=" <<   curpos   << endl;
#endif

    // Read time set
    if (curpos < reclen -1){
        CnField<string> timeset(buf+curpos, en);
        time_set.set(timeset.getData(), curpos, timeset.getByteCount(), timeset.getTotalByteCount());
        curpos += time_set.getTotalByteCount();
    }
#if _DEBUG
    cout << "after time_set curpos=" <<   curpos   << endl;
#endif
    // Read op code
    if (curpos < reclen -1){
        CnField<string> opcode(buf+curpos, en);
        op_code.set(opcode.getData(), curpos, opcode.getByteCount(), opcode.getTotalByteCount());
        curpos += op_code.getTotalByteCount();
    }
#if _DEBUG
    cout << "after op_code curpos=" <<   curpos   << endl;
#endif
    // Read test description text
    if (curpos < reclen -1){
        CnField<string> testtxt(buf+curpos, en);
        test_txt.set(testtxt.getData(), curpos, testtxt.getByteCount(), testtxt.getTotalByteCount());
        curpos += test_txt.getTotalByteCount();
    }
#if _DEBUG
    cout << "after test_txt curpos=" <<   curpos   << endl;
#endif
    // Read alarm id
    if (curpos < reclen -1){
        CnField<string> alrmid(buf+curpos, en);
        alrm_id.set(alrmid.getData(), curpos, alrmid.getByteCount(), alrmid.getTotalByteCount());
        curpos += alrm_id.getTotalByteCount();
    }
#if _DEBUG
    cout << "after alrm_id curpos=" <<   curpos   << endl;
#endif
    // Read additional program information
    if (curpos < reclen -1){
        CnField<string> progtxt(buf+curpos, en);
        prog_txt.set(progtxt.getData(), curpos, progtxt.getByteCount(), progtxt.getTotalByteCount());
        curpos += prog_txt.getTotalByteCount();
    }
#if _DEBUG
    cout << "after prog_txt curpos=" <<   curpos   << endl;
#endif
    // Read additional result information
    if (curpos < reclen -1){
        CnField<string> rslttxt(buf+curpos, en);
        rslt_txt.set(rslttxt.getData(), curpos, rslttxt.getByteCount(), rslttxt.getTotalByteCount());
        curpos += rslt_txt.getTotalByteCount();
    }
#if _DEBUG
    cout << "after rslt_txt curpos=" <<   curpos   << endl;
#endif
    // Read pattern generator number
    if (curpos < reclen -1){
        NmField<unsigned int, 1 > patgnum(buf+curpos, en);
        patg_num.set(patgnum.getData(), curpos, patg_num.getByteCount(), patgnum.getTotalByteCount());
        curpos += patg_num.getTotalByteCount();
    }
#if _DEBUG
    cout << "after patg_num curpos=" <<   curpos   << endl;
#endif
    // Read bitmap enabled comparator
    if (curpos < reclen -1){
        NmField<unsigned int, 1 > spinmap(buf+curpos, en);
        spin_map.set(spinmap.getData(), curpos, spinmap.getByteCount(), spinmap.getTotalByteCount());
    }
#if _DEBUG
    cout << "after spin_map curpos=" <<   curpos   << endl;
#endif
}


// to read flag setting
bool Ftr::getFlagSetting(StdfField<vector<bool> >& stdffield, int pos) const {
    vector<bool> vec = stdffield.getData();
    return vec[pos];


}
